//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Shp.Runtime.Sitka.ServiceAgent;
using Shp.Runtime.Sitka.ServiceAgent.Managers;
using Shp.Runtime.OfflineSitka;
using Shp.Runtime.Contract;
using System.Globalization;
using Shp.Runtime.Sitka.ServiceGateway.SitkaClient;

namespace Shp.Runtime.DataModel.Sitka.Tests
{
    internal class MetadataInitialize
    {
        public const string JobSearchViewName = "jobSearch";
        public const string JobSearchViewId = "4453d801-2027-4e87-aebc-52aaaf507269";
        public const string JobDetailViewName = "jobDetail";
        public const string JobDetailViewId =  "0c7063d6-fcd7-4341-9732-3361d89da33b";

        public string TenantAlias { get; set; }
        public Guid TenantId { get; set; }
        public string Container { get; set; }

        public MetadataInitialize()
        {
            TenantId = Guid.NewGuid();
            TenantAlias = Guid.NewGuid().ToString().Replace('-', 'x');
        }

        private void AddType(string name, string id)
        {
            Entity entity = EntityManager.CreateEntity("Type", id);
            entity.Properties.Add("Name", name);
            InsertEntity(entity);
        }

        public void CreateTypes()
        {
            AddType("Boolean (Yes | No)", "a82c6a4f-0389-4882-bd23-1ccf13a3c63e");
            AddType("Long text (up to 4000 characters)", "b44a04ca-3426-4c8d-9fc0-431de22d6f4e");
            AddType("Short text (up to 255 characters)", "fa564e7c-f59b-480f-a768-a1d02a34e32c");
            AddType("Number", "8863152f-f10e-4f7d-819f-b4bf05eb8b24");
            AddType("Date and time", "018d42ba-ca23-4e15-9c01-e941c86dd36f");
        }

        public const string PositionEntityDefId = "750438de-31a2-4d87-b0c6-28563840947c";

        public void CreateEntityDef()
        {
            Entity entity = EntityManager.CreateEntity("EntityDef",PositionEntityDefId);
            entity.Properties.Add("Name", "position");

            InsertEntity(entity);   
        }

        public void AddEntityDefField(string name, bool isVisibleFromApplicationForm)
        {
            Entity entity = EntityManager.CreateEntity("EntityDefField", Guid.NewGuid().ToString());
            entity.Properties.Add("Name", name);
            entity.Properties.Add("TypeId", "b44a04ca-3426-4c8d-9fc0-431de22d6f4e");
            entity.Properties.Add("IsShared", false);
            entity.Properties.Add("EntityDefId", "750438de-31a2-4d87-b0c6-28563840947c");
            entity.Properties.Add("TenantId", TenantId.ToString());
            entity.Properties.Add("IsVisibleFromApplicationForm", isVisibleFromApplicationForm);

            InsertEntity(entity);
        }

        private void AddEntityDefField(string name, string typeId, string id)
        {
            Entity entity = EntityManager.CreateEntity("EntityDefField", Guid.NewGuid().ToString());
            entity.Properties.Add("Name", name);
            entity.Properties.Add("TypeId", typeId);
            entity.Properties.Add("IsShared", true);
            entity.Properties.Add("EntityDefId", "750438de-31a2-4d87-b0c6-28563840947c");
            entity.Properties.Add("TenantId", TenantId.ToString());

            InsertEntity(entity);
        }

        public void CreateEntityDefFields()
        {
            AddEntityDefField("postedOn", "018d42ba-ca23-4e15-9c01-e941c86dd36f", "1b13bc12-86cf-483e-8501-17b191d4c2ef");
            AddEntityDefField("code", "fa564e7c-f59b-480f-a768-a1d02a34e32c", "31ec638a-d4b3-4211-b10a-aaae20e9cbf0");
            AddEntityDefField("title", "fa564e7c-f59b-480f-a768-a1d02a34e32c", "e24115b0-3ac7-44a5-a961-d0d349cb7184");
        }

        public void AddTenant(string tenantId, string tenantAlias, string layout)
        {
            Entity entity = EntityManager.CreateEntity("Tenant", tenantId);
            entity.Properties.Add("Name", "name");
            entity.Properties.Add("Alias", tenantAlias);
            entity.Properties.Add("SilverlightAccountId", Guid.NewGuid().ToString());
            entity.Properties.Add("SilverlightAccountKey", Guid.NewGuid().ToString());
            entity.Properties.Add("Style", Guid.NewGuid().ToString());
            entity.Properties.Add("Layout", layout);

            InsertEntity(entity);  
        }

        public void AddTenant(string tenantId, string tenantAlias, Guid style)
        {
            Entity entity = EntityManager.CreateEntity("Tenant", tenantId);
            entity.Properties.Add("Name", "name");
            entity.Properties.Add("Alias", tenantAlias);
            entity.Properties.Add("SilverlightAccountId", Guid.NewGuid().ToString());
            entity.Properties.Add("SilverlightAccountKey", Guid.NewGuid().ToString());           
            entity.Properties.Add("Style", style.ToString());

            InsertEntity(entity);
        }

        public void AddTenant(string tenantId, string tenantAlias)
        {
            Entity entity = EntityManager.CreateEntity("Tenant", tenantId);
            entity.Properties.Add("Name", "name");
            entity.Properties.Add("Alias", tenantAlias.ToLower());
            entity.Properties.Add("SilverlightAccountId", Guid.NewGuid().ToString());
            entity.Properties.Add("SilverlightAccountKey", Guid.NewGuid().ToString());
            entity.Properties.Add("Style", Guid.NewGuid().ToString());
            entity.Properties.Add("Layout", (0).ToString(CultureInfo.InvariantCulture));

            InsertEntity(entity);            
        }

        public void AddWorkflow(Guid id, string name, string xoml)
        {
            Entity entity = EntityManager.CreateEntity("workflowDef", id.ToString());
            entity.Properties = new Dictionary<string, object>();
            entity.Properties.Add("Name", name);
            entity.Properties.Add("Xoml", xoml);

            InsertEntity(entity);
        }

        public void CreateTenant()
        {
            AddTenant(TenantId.ToString(), TenantAlias.ToLower());            
        }

        public void CreateViewDef()
        {
            Entity entity = EntityManager.CreateEntity("ViewDef", JobDetailViewId);
            entity.Properties.Add("Name", JobDetailViewName);

            InsertEntity(entity);

            entity = EntityManager.CreateEntity("ViewDef", JobSearchViewId);
            entity.Properties.Add("Name", JobSearchViewName);

            InsertEntity(entity);
        }        

        private void AddViewDefField(string id, string viewDefId, string name, string label, int ordinal)
        {
            Entity entity = EntityManager.CreateEntity("ViewDefField", id);
            entity.Properties.Add("ViewDefId", viewDefId);
            entity.Properties.Add("Name", name);
            entity.Properties.Add("Label", label);
            entity.Properties.Add("Ordinal", ordinal.ToString());
            entity.Properties.Add("TenantId", TenantId.ToString());

            InsertEntity(entity);
        }

        public void CreateViewDefFields()
        {
            AddViewDefField("89ea0bb9-8e47-4e4f-aa94-348b51fc157a", "4453d801-2027-4e87-aebc-52aaaf507269", "location", "Location", 1);
            AddViewDefField("5466d9a8-7251-4a23-8d91-784f0f2c6e22", "0c7063d6-fcd7-4341-9732-3361d89da33b", "location", "Location", 1);
            AddViewDefField("c0fce8c3-7692-4bcf-8cfe-80801759bc46", "0c7063d6-fcd7-4341-9732-3361d89da33b", "code", "Detail Code", 0);
            AddViewDefField("8f7d9e9b-61b1-483a-b0e0-91fee8541a1b", "4453d801-2027-4e87-aebc-52aaaf507269", "title", "Title", 2);
            AddViewDefField("b1b1a278-a7b5-4993-901a-b16283f2ffc9", "4453d801-2027-4e87-aebc-52aaaf507269", "code", "REF", 0);
        }

        private void InsertEntity(Entity entity)
        {
            DefaultTenantManager tmanager = new DefaultTenantManager();

            Scope scope = new Scope();
            scope.AuthorityId = tmanager.GetAuthorityId(Container);
            scope.ContainerId = Container;

            ISitkaSoapService stratusProxy = SitkaProxyFactory.BuildProxy(tmanager);
            
            stratusProxy.Create(scope, entity);                        
        }

        internal void DeleteEntity(string entityId)
        {

            DefaultTenantManager tmanager = new DefaultTenantManager();

            Scope scope = new Scope();
            scope.AuthorityId = tmanager.GetAuthorityId(Container);
            scope.ContainerId = Container;
            scope.EntityId = entityId;

            ISitkaSoapService stratusProxy = SitkaProxyFactory.BuildProxy( tmanager);

            stratusProxy.Delete(scope);
        }

        public static EntityField GetEntityFieldDef(string name)
        {
            EntityField field = new EntityField();
            field.IsShared = false;
            field.Name = name;            
            field.TypeId = new Guid("b44a04ca-3426-4c8d-9fc0-431de22d6f4e");
            field.TypeName = "Long text (up to 4000 characters)";
            return field;
        }

        private void AddAuthorization(string actionId, string tenantId, string credential)
        {
            Entity entity = EntityManager.CreateEntity("Authorization", Guid.NewGuid().ToString());
            entity.Properties.Add("ActionId", actionId);
            entity.Properties.Add("TenantId", tenantId);
            entity.Properties.Add("Credential", credential);            

            InsertEntity(entity);
        }

        private string AddAction(string uri, string description, bool isSystem)
        {
            string actionId = Guid.NewGuid().ToString();
            Entity entity = EntityManager.CreateEntity("Action", actionId);
            entity.Properties.Add("Uri", uri);
            entity.Properties.Add("Description", description);
            entity.Properties.Add("IsSystem", isSystem);

            InsertEntity(entity);
            return actionId;
        }

        public Guid TestAuthorizationTenant1 { get; set; }
        public Guid TestAuthorizationTenant2 { get; set; }
        public Guid TestAuthorizationTenant3 { get; set; }
        public Guid TestAuthorizationTenant4 { get; set; }

        public Guid ActionId1 { get; set; }
        public Guid ActionId2 { get; set; }
        public Guid ActionId3 { get; set; }

        public void CreateActionsAndAuthorizations()
        {
            TestAuthorizationTenant1 = Guid.NewGuid();
            AddTenant(TestAuthorizationTenant1.ToString(), "TestAuthorizationTenant1");

            TestAuthorizationTenant2 = Guid.NewGuid();
            AddTenant(TestAuthorizationTenant2.ToString(), "TestAuthorizationTenant2");

            TestAuthorizationTenant3 = Guid.NewGuid();
            AddTenant(TestAuthorizationTenant3.ToString(), "TestAuthorizationTenant3");

            TestAuthorizationTenant4 = Guid.NewGuid();
            AddTenant(TestAuthorizationTenant4.ToString(), "TestAuthorizationTenant4");

            string action1 = AddAction(@"http://tempuri.org/IDatamodelSC/UpdateViewDef", "Update View Definition", false);
            string action2 = AddAction(@"http://tempuri.org/IProcessSC/GetRecruitingWorkflowListByApplicant", "Get Recruiting WorkflowList By Applicant", false);
            string action3 = AddAction(@"http://tempuri.org/ISystemSC/Ping", "Ping", true);

            ActionId1 = new Guid(action1);
            ActionId2 = new Guid(action2);
            ActionId3 = new Guid(action3);

            //TestAuthorizationTenant1
            AddAuthorization(action1, TestAuthorizationTenant1.ToString(), "credential1");
            AddAuthorization(action2, TestAuthorizationTenant1.ToString(), "credential1");            

            //TestAuthorizationTenant2
            AddAuthorization(action1, TestAuthorizationTenant2.ToString(), "credential1");
            AddAuthorization(action2, TestAuthorizationTenant2.ToString(), "credential2");

            //TestAuthorizationTenant3            

            //TestAuthorizationTenant4
            AddAuthorization(action2, TestAuthorizationTenant4.ToString(), "credential1");

        }

        internal void AddStyle(Guid styleId, Guid tenantId, string name, string url)
        {
            Entity entity = EntityManager.CreateEntity("style", styleId.ToString());
            
            entity.Properties.Add("TenantId", tenantId.ToString());
            entity.Properties.Add("Name", name);
            entity.Properties.Add("Url", url);

            InsertEntity(entity);
        }

        internal void AddMainMenu(Guid mainMenuId, Guid tenantId, string description, string url, bool isPublic, int ordinal)
        {
            Entity entity = EntityManager.CreateEntity("MainMenu", mainMenuId.ToString());
            entity.Properties.Add("TenantId", tenantId.ToString());
            entity.Properties.Add("Description", description);
            entity.Properties.Add("Url", url);
            entity.Properties.Add("IsPublic", isPublic);
            entity.Properties.Add("Ordinal", ordinal.ToString(CultureInfo.InvariantCulture));

            InsertEntity(entity);
        }

        internal void AddTenant(string tenantId, int layout, Guid style)
        {
            //create tenant
            Entity entity = EntityManager.CreateEntity("tenant", tenantId);
            entity.Properties.Add("Name", "name");
            entity.Properties.Add("Alias", "alias");
            entity.Properties.Add("SilverlightAccountId", Guid.NewGuid().ToString());
            entity.Properties.Add("SilverlightAccountKey", Guid.NewGuid().ToString());
            entity.Properties.Add("Style", style.ToString());
            entity.Properties.Add("Layout", layout.ToString(CultureInfo.InvariantCulture));

            InsertEntity(entity);  
        }
    }
}
